<template>
  <div class="html1_12">
    <h1>1.12 使用canvas API画图</h1>
    <p>
      <pre>
        &lt;canvas> 是 HTML5 新增的，一个可以使用脚本(通常为 JavaScript) 在其中绘制图像的 HTML 元素。它可以用来制作照片集或者制作简单(也不是那么简单)的动画，甚至可以进行实时视频处理和渲染。
&lt;canvas>的基本使用方法
		&lt;canvas id="tutorial" width="300" height="300" style="border: 1px solid red;">你的浏览器不支持 canvas，请升级浏览器版本或者更换其他浏览器&lt;/canvas>
注：支持 &lt;canvas> 的浏览器会只渲染 &lt;canvas> 标签，而忽略其中的替代内容。不支持 &lt;canvas> 的浏览器则 会直接渲染替代内容。用文本替换。所以可以在标签内添加内容提示用户浏览器是否支持&lt;canvas>标签。
&lt;canvas> 看起来和 &lt;img> 标签一样，只是 &lt;canvas> 只有两个可选的属性 width、heigth 属性，而没有 src、alt 属性。
​如果不给 &lt;canvas> 设置 widht、height 属性时，则默认 width为300、height 为 150，单位都是 px。也可以使用 css 属性来设置宽高，但是如宽高属性和初始比例不一致，他会出现扭曲。所以，建议永远不要使用 css 属性来设置 &lt;canvas> 的宽高。
      </pre>
    </p>
      <div class="html1_12_1">
        <h2>1.12.1 canvas的基本元素</h2>
        <p>
          <pre>
            获取画布的上下文 
&lt;canvas> 会创建一个固定大小的画布，会公开一个或多个渲染上下文(画笔)，使用渲染上下文来绘制和处理要展示的内容
var canvas = document.getElementById('MyCanvas');
			//获得 2d 上下文对象
if(!canvas.getContext) return;
			var ctx = canvas.getContext('2d');
     canvas坐标与颜色 
ctx.fillStyle='#FF0000';
ctx.fillRect(0,0,80,100);
          </pre>
        </p>
      </div>
      <div class="html1_12_2">
        <h2>1.12.2  canvas设置画布绘制状态</h2>
        <p>
          <pre>
            1 设置线条连接样式
图形的基本元素是路径。路径是通过不同颜色和宽度的线段或曲线相连形成的不同形状的点的集合。一个路径，甚至一个子路径，都是闭合的。使用路径绘制图形需要一些额外的步骤：
创建路径起始点
调用绘制方法去绘制出路径
把路径封闭
一旦路径生成，我们就能通过描边或填充路径区域来渲染图形。
下面是需要用到的方法：
1，beginPath()
新建一条路径，路径一旦创建成功，图形绘制命令被指向到路径上生成路径
ctx.beginPath(); //新建一条path
2，moveTo(x1, y1)
把画笔移动到指定的坐标(x1, y1)。相当于设置路径的起始点坐标。
ctx.moveTo(50, 50); //把画笔移动到指定的坐标
3，lineTo(x2,y2)
绘制一条从（x1，y1）到指定坐标（x2，y2）的一条直线
注：如果（x1，y1）和（x2，y2）两点坐标一样则什么都不发生。
ctx.lineTo(200, 80); //绘制一条从当前位置到指定坐标(200, 50)的直线.
3，closePath()
闭合路径之后，图形绘制命令又重新指向到上下文中
注：如果绘制了两条线，这两条线不在一条直线上时，使用closePath会自动连接成一个三角形。
4，stroke()
通过线条来绘制图形轮廓
注：stroke不会自动closePath()
2 设置填充和笔触样式 
以上步骤完成之后我们可以通过fill（）方法将闭合路径内部填充
fill()通过填充路径的内容区域生成实心的图形
ctx.beginPath(); //新建一条path
ctx.moveTo(50, 50); //把画笔移动到指定的坐标
ctx.lineTo(200, 80);//绘制一条从当前位置到指定坐标(200, 50)的直线.
ctx.lineTo(100, 80);//闭合路径。会拉一条从当前点到path起始点的直线。如果当前点与起始点重合，则什么都不做
ctx.closePath();
ctx.stroke(); //绘制路径。
ctx.fill();
这样我们就能得到一个填充好的闭合路径了。
此外，填充的颜色可以通过fillStyle方法来设置。
我们不仅可以设置路径图案的外观，我们也可以设置路径本身的属性，通过不同的方式，我们能将路径的颜色改变，还有路径的线宽，以及线段末端样式（线段末端以方块，圆形结束）等属性，我们都可以通过相应的方法和属性改变。
strokeStyle=color		改变路径的颜色
line style=x			改变路径线宽（x默认为1.0且只能为正值）
lineCap=type			改变线条末端样式（type共有三个值
1，butt：线段末端以方形结束
2，round：线段末端以圆形结束
3，square：线段末端以方形结束，但是增加了一个宽度和线段相同，高度是线段厚度一半的矩形区域。）
          </pre>
        </p>
        <img src="../assets/images/2.47.png" alt="">
        <p></p>
        <p>
          <pre>
            3 使用渐变 
渐变可以填充在矩形, 圆形, 线条, 文本等等, 各种形状可以自己定义不同的颜色。以下有两种不同的方式来设置Canvas渐变：
createLinearGradient(x,y,x1,y1) - 创建线条渐变
createRadialGradient(x,y,r,x1,y1,r1) - 创建一个径向/圆渐变
当我们使用渐变对象，必须使用两种或两种以上的停止颜色。
addColorStop()方法指定颜色停止，参数使用坐标来描述，可以是0至1.
使用渐变，设置fillStyle或strokeStyle的值为渐变，然后绘制形状，如矩形，文本，或一条线。
createLinearGradient(x,y,x1,y1) - 创建线条渐变
参数	    描述
x0	        渐变开始点的 x 坐标
y0			渐变开始点的 y 坐标
x1			渐变结束点的 x 坐标
y1			渐变结束点的 y 坐标
使用 createLinearGradient()://创建一个线性渐变，使用渐变填充矩形
实例：
function draw() {
				var canvas = document.getElementById('MyCanvas02');
				if(!canvas.getContext) return;
				var ctx = canvas.getContext("2d");
				// 创建渐变
				var grd=ctx.createLinearGradient(0,0,200,0);
				grd.addColorStop(0,"red");
				grd.addColorStop(1,"white");
				// 填充渐变
				ctx.fillStyle=grd;
				ctx.fillRect(10,10,150,80);
			}
			draw();
效果图：
          </pre>
        </p>
        <img src="../assets/images/2.48.png" alt="">
        <p></p>
        <p>
          <pre>
            4 使用径向渐变  
createRadialGradient(x,y,r,x1,y1,r1) - 创建一个径向/圆渐变
参数	描述
x0		渐变的开始圆的 x 坐标
y0		渐变的开始圆的 y 坐标
r0		开始圆的半径
x1		渐变的结束圆的 x 坐标
y1		渐变的结束圆的 y 坐标
r1		结束圆的半径
使用 createRadialGradient():创建一个径向渐变，使用径向渐变填充矩形
实例：
function draw() {
				var canvas = document.getElementById('MyCanvas03');
				if(!canvas.getContext) return;
				var ctx = canvas.getContext("2d");
				// 创建渐变
				var grd=ctx.createRadialGradient(75,50,5,90,60,100);
				grd.addColorStop(0,"red");
				grd.addColorStop(1,"white");
				// 填充渐变
				ctx.fillStyle=grd;
				ctx.fillRect(10,10,150,80);
			}
			draw();
效果图：
          </pre>
        </p>
        <img src="../assets/images/2.49.png" alt="">
        <p></p>
        <p>
          <pre>
            5保存和恢复绘制状态 
Saving and restoring state是绘制复杂图形时必不可少的操作。save() 和 restore()。save和restore 方法是用来保存和恢复canvas状态的，都没有参数。
​	Canvas的状态就是当前画面应用的所有样式和变形的一个快照。
1、关于 save() ：Canvas状态存储在栈中，每当save()方法被调用后，当前的状态就被推送到栈中保存。
一个绘画状态包括：
① 当前应用的变形（即移动，旋转和缩放）
②strokeStyle, fillStyle, globalAlpha, lineWidth, lineCap, lineJoin, miterLimit, shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor, globalCompositeOperation 的值
③当前的裁切路径（clipping path）
可以调用任意多次 save方法(类似数组的 push())。
2、关于restore()：每一次调用 restore 方法，上一个保存的状态就从栈中弹出，所有设定都恢复(类似数组的 pop())。
实例：
var canvas = document.getElementById('MyCanvas04');
				if(!canvas.getContext) return;
				var ctx = canvas.getContext("2d");
				ctx.fillRect(0, 0, 150, 150); // 使用默认设置绘制一个矩形
				ctx.save(); // 保存默认状态
				ctx.fillStyle = 'red' // 在原有配置基础上对颜色做改变
				ctx.fillRect(15, 15, 120, 120); // 使用新的设置绘制一个矩形
				ctx.save(); // 保存当前状态
				ctx.fillStyle = '#FFF' // 再次改变颜色配置
				ctx.fillRect(30, 30, 90, 90); // 使用新的配置绘制一个矩形
				ctx.restore(); // 重新加载之前的颜色状态
				ctx.fillRect(45, 45, 60, 60); // 使用上一次的配置绘制一个矩形
				ctx.restore(); // 加载默认颜色配置
				ctx.fillRect(60, 60, 30, 30); // 使用加载的配置绘制一个矩形
效果图如下：
          </pre>
        </p>
        <img src="../assets/images/2.50.png" alt="">
        <p></p>
        <p>
          <pre>
            可以发现矩形的fillstyle共变化了4次。先是save（）了fillStyle默认的黑色填充颜色将其设置成了红色，然后再次save了红色的填充色，变更为白色。之后使用了restore（）重新加载了上一次save的红色填充色，重置了填充色，最后再次使用restore把最开始保存的黑色设为填充物的颜色。由此可以看出save（）和restore（）与数组的push（）和pop（）性质类似。 
          </pre>
        </p>
      </div>
      <div class="html1_12_3">
        <h2>1.12.3 canvas绘制图像</h2>
        <p>
          <pre>
            drawImage() 方法在画布上绘制图像、画布或视频。drawImage() 方法也能够绘制图像的某些部分，以及/或者增加或减少图像的尺寸。
在画布上定位图像：
context.drawImage(img,x,y);
在画布上定位图像，并规定图像的宽度和高度：
context.drawImage(img,x,y,width,height);
剪切图像，并在画布上定位被剪切的部分：
context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);
参数		描述
img			规定要使用的图像、画布或视频。	 
sx			可选。开始剪切的 x 坐标位置。
sy			可选。开始剪切的 y 坐标位置。
swidth		可选。被剪切图像的宽度。
sheight		可选。被剪切图像的高度。
x			在画布上放置图像的 x 坐标位置。
y			在画布上放置图像的 y 坐标位置。
width		可选。要使用的图像的宽度（伸展或缩小图像）。
height		可选。要使用的图像的高度（伸展或缩小图像）。

1 使用视频图像 
实例：
&lt;video id="video1" controls width="270" autoplay>
			&lt;source src="../Source/movie.ogg" type='video/ogg'>
&lt;/video>
		&lt;p>画布 (代码在每20毫秒绘制当前的视频帧):&lt;/p>
		&lt;canvas id="myCanvas05"  style="border:1px solid #d3d3d3;">您的浏览器不支持 HTML5 canvas 标签。&lt;/canvas>
		&lt;script>
			var v = document.getElementById("video1");
			var c = document.getElementById("myCanvas05");
			ctx = c.getContext('2d');
			v.addEventListener('play', function() {
				var i = window.setInterval(function() {
					ctx.drawImage(v, 5, 5, 260, 125)
				}, 20);
			}, false);
			v.addEventListener('pause', function() {
				window.clearInterval(i);
			}, false);
			v.addEventListener('ended', function() {
				clearInterval(i);
			}, false);
		&lt;/script>
效果图：
          </pre>
        </p>
        <video src="../assets/h5实例视频/canvas标签.mp4" width="600px" controls></video>
       <img src="../assets/images/2.51.png" alt="">
       <p></p>
       <p>
         <pre>
           Canvas每隔20毫秒绘制当前的视屏帧，以显示视频。
2 使用画布图像
&lt;p>要使用的图片:&lt;/p>
		&lt;img id="flower" src="Source/flower.jpg" style="width: 250px;height: 300px;">
		&lt;p>画布:&lt;/p>
		&lt;canvas id="myCanvas06" width="250" height="300" style="border:1px solid #d3d3d3;">
		您的浏览器不支持 HTML5 canvas 标签。
		&lt;/canvas>
		&lt;canvas id="myCanvas0602" width="250" height="300" style="border:1px solid #d3d3d3;">
		您的浏览器不支持 HTML5 canvas 标签。
		&lt;/canvas>
		&lt;script>
		var c=document.getElementById("myCanvas06");
		var ctx=c.getContext("2d");
		var c2=document.getElementById("myCanvas0602");
		var ctx2=c2.getContext("2d");
		var img=document.getElementById("flower");
		img.onload = function()
		{
		    ctx.drawImage(img,10,10,150,180);
			//按照150*180大小绘制图片
		    ctx2.drawImage(img,120,50,220,200,10,10,220,200);
			//在图片的（120,50）点处剪切一张220*200大小的截图放在canvas画布的（10,10）的位置处。
		}
&lt;/script>
	效果图：
         </pre>
       </p>
       <img src="../assets/images/2.52.png" alt="">
      </div>
      <div class="html1_12_4">
        <h2>1.12.4 canvas绘制图形</h2>
        <p>
          <pre>
            有两个方法可以绘制圆弧：
1、arcTo(x1, y1, x2, y2, radius): 根据给定的控制点和半径画一段圆弧，最后再以直线连接两个控制点。
注：arcTo 方法的说明：这个方法可以这样理解。
绘制的弧形是由两条切线所决定。
第 1 条切线：起始点和控制点1决定的直线。
第 2 条切线：控制点1 和控制点2决定的直线。
其实绘制的圆弧就是与这两条直线相切的圆弧。
2、arc(x, y, r, startAngle, endAngle, anticlockwise): 以(x, y)为圆心，以r为半径，从 startAngle弧度开始到endAngle弧度结束。anticlosewise是布尔值，true表示逆时针，false表示顺时针(默认是顺时针)。
注意：这里的度数都是弧度。（radians=(Math.PI/180)*degrees   //角度转换成弧度）
实例：
&lt;canvas id="myCanvas0701" width="250" height="300" style="border:1px solid #d3d3d3;">
		您的浏览器不支持 HTML5 canvas 标签。
		&lt;/canvas>
		&lt;canvas id="myCanvas0702" width="250" height="300" style="border:1px solid #d3d3d3;">
		您的浏览器不支持 HTML5 canvas 标签。
		&lt;/canvas>
		&lt;script>
		function draw(){
		var c=document.getElementById("myCanvas0701");
		if (!c.getContext) return;
		var ctx=c.getContext("2d");
		var c2=document.getElementById("myCanvas0702");
		if (!c2.getContext) return;
		var ctx2=c2.getContext("2d");
		ctx.beginPath();
		ctx.moveTo(50, 50);
		//参数1、2：控制点1坐标 参数3、4：控制点2坐标 参数4：圆弧半径
		ctx.arcTo(200, 50, 200, 200, 100);
		ctx.lineTo(200, 200)
		ctx.stroke();
		ctx.beginPath();
		ctx.rect(50, 50, 10, 10);
		ctx.rect(200, 50, 10, 10)
		ctx.rect(200, 200, 10, 10)
		ctx.fill();
		
		ctx2.beginPath();
		ctx2.arc(50, 200, 150, 0,( Math.PI * 3)/2, true);
		ctx2.stroke();
		}
		draw();
		&lt;/script>
效果图：
          </pre>
        </p>
       <img src="../assets/images/2.53.png" alt="">
      </div>
      <div class="html1_12_5">
        <h2>1.12.5 canvas 绘制文本</h2>
        <p>
          <pre>
            canvas 提供了两种方法来渲染文本:
1、fillText(text, x, y) 在指定的 (x,y) 位置填充指定的文本。
2、strokeText(text, x, y) 在指定的 (x,y) 位置绘制文本边框。
实例：
&lt;canvas id="MyCanvas08" width="650px" height="300px" style="border: 1px solid red;" >你的浏览器不支持 canvas，请升级你的浏览器。&lt;/canvas>
    &lt;script>
       function draw() {
                var canvas = document.getElementById('MyCanvas08');
                if(!canvas.getContext) return;
                var ctx = canvas.getContext("2d");
                ctx.font = "30px sans-serif"
                ctx.fillText("5G网络升级进行时 独立组网将成未来主旋律", 10, 100);
                ctx.strokeText("老人最担心支付安全“折中”方式可解决", 10, 200)
            }
            draw();
    &lt;/script>
效果图：
          </pre>
        </p>
       <img src="../assets/images/2.54.png" alt="">
       <p></p>
       <p>
         <pre>
此外我们还可以给文本添加样式
font = value 当前我们用来绘制文本的样式。这个字符串使用和 CSS font 属性相同的语法。 默认的字体是 10px sans-serif。
textAlign = value 文本对齐选项。可选的值包括：start, end, left, right or center。 默认值是 start。
textBaseline = value 基线对齐选项，可选的值包括：top, hanging, middle, alphabetic, ideographic, bottom。默认值是 alphabetic。。
direction = value 文本方向。可能的值包括：ltr, rtl, inherit。默认值是 inherit。
         </pre>
       </p>
      </div>
      <div class="html1_12_6">
        <h2>1.12.6 canvas特效</h2>
        <p>
          <pre>
            1 使用阴影 
&lt;canvas>有多个与阴影相关的属性：
	shadowOffsetX	阴影在X轴的偏移量，单位为像素。默认值为0，阴影位于图形正下方，阴影是不可见的。大于0向右偏移，小于0向左偏移。阴影偏移量越大，产生的阴影也越大，同时会感觉绘制的图形在画布是浮得也越高
	shadowOffsetY	阴影在Y轴的偏移量，单位为像素。默认值为0，阴影位于图形正下方，阴影是不可见的。大于0向下偏移，小于0向上偏移。阴影偏移量越大，产生的阴影也越大，同时会感觉绘制的图形在画布是浮得也越高
	shadowColor		阴影的颜色，其默认值为完全透明的黑色。因此，如果没有把该属性设置为不透明，则阴影是不可见的。该属性只能设置为一个表示颜色的字符串，不能使用渐变或图案。使用半透明的阴影可以产生很逼真的阴影效果，因为透过阴影还能看到背景
	shadowBlur		阴影的模糊值。是一个与像素无关的值，被用于高斯模糊方程中，以便对阴影进行模糊化处理。默认值为0，表示产生一个清晰的阴影。该值越大，表示阴影越模糊
注：根据canvas规范，只有在满足以下两个条件时，浏览器才会绘制阴影：1）指定了一个非全透明的shadowColor属性值；2）shadowOffsetX、shadowOffsetY、shadowBlur三个属性中，至少有一个属性的值不是0。

2 使用透明度 
globalAlpha 属性设置或返回绘图的当前透明值（alpha 或 transparency）。
globalAlpha 属性值必须是介于 0.0（完全透明） 与 1.0（不透明） 之间的数字。
context.globalAlpha=number;（number取值区间为【0.0---1.0】默认值：1.0）

3 使用合成 
事实上&lt;canvas>标签的本质就是一张图片，但是这个图片是作为一块“画布”，同时我们可以使用多种方法或者更改相应属性作为我们的“画笔”来绘制这张“画布”，通过图片的剪切，透明度和大小以及文字的大小，颜色，透明度的设置就可以完成想要的图片的合成。
在我们完成我们所需要的需求的时候，我们只要在网页上右击图片另存为即可获得我们想要合成的图片。
          </pre>
        </p>
      </div>
      <div class="html1_12_7">
        <h2>1.12.7 canvas图形几何变化</h2>
        <p>
          <pre>
            1 移动
位移 translate(x,y) : 将canvas画布进行位移显示。将坐标原点移动到(x,y)的位置，translate将原点移动之后，如果再次调用translate进行移动，那么会依照上一个translate移动之后作为原点参考。
2 缩放 
缩放 scale(sx,sy) : 将canvas画布进行缩放显示
注：sx缩放当前绘图的宽度（1=100%，0.5=50%，2=200%，依次类推）。
sy缩放当前绘图的高度（1=100%，0.5=50%，2=200%，依次类推）。
3 旋转
旋转 rotate(deg) : 将canvas画布进行旋转显示
注：旋转角度deg，以弧度计。如需将角度转换为弧度，请使用 degrees*Math.PI/180 公式进行计算。（如需旋转5度，可规定下面的公式：5*Math.PI/180）。 
实例：
	&lt;canvas id="MyCanvas09" width="600px" height="600px" style="border: 1px solid red;">你的浏览器不支持
        canvas，请升级你的浏览器。&lt;/canvas>
    &lt;script>
        function draw() {
            var canvas = document.getElementById('MyCanvas09');
            if (!canvas.getContext) return;
            var ctx = canvas.getContext("2d");
            var img = document.getElementById("flower");
            ctx.globalAlpha = 0.7; //设置透明度
            ctx.shadowOffsetX = 20;
            ctx.shadowOffsetY = 20;
            ctx.shadowColor = "blue";
            ctx.shadowBlur = 20; //设置阴影
            ctx.font = "50px sans-serif" //设置字体大小
            ctx.fillText("社会·法治", 10, 100);

            ctx.save(); //保存canvas画布设置
            ctx.translate(70, 70); //将原点位移到原来坐标系（70,70）的位置
            ctx.fillStyle = 'red';
            ctx.fillText("社会·法治", 10, 100); //红色字体为位移之后字体
            ctx.save();
            ctx.fillStyle = 'yellow';
            ctx.rotate(50 * Math.PI / 180);
            ctx.fillText("社会·法治", 10, 200); //黄色字体为旋转之后字体
            ctx.restore();
            ctx.scale(2, 2);
            ctx.fillStyle = 'pink';
            ctx.fillText("社会·法治", 10, 200); //粉色字体为缩放之后字体
        }
        draw();
    &lt;/script>
          </pre>
        </p>
       <img src="../assets/images/2.55.png" alt="">
      </div>
  </div>
</template>

<script>
export default {};
</script>

<style>
</style>